<template>
  <div ref="container" class="image-marker-container" :style="{width: width, height: height}">
    <div class="image-wrapper">
      <!-- 图片和标点的容器 -->
      <div 
        class="marker-main"
        :class="{ 'dragging': isDragging }"
        :style="{
          backgroundImage: `url(${currentBackgroundImage})`,
          backgroundSize: 'contain',
          backgroundPosition: 'center',
          backgroundRepeat: 'no-repeat',
          width: '100%',
          height: '100%',
          position: 'relative',
          cursor: getCursor,
          transform: `scale(${scale}) translate(${position.x}px, ${position.y}px)`,
          transformOrigin: '0 0'
        }"
        @click="handleContainerClick"
        @contextmenu.prevent.stop="handleRightClick"
        @wheel.prevent="handleWheel"
        @mousedown="handlePanStart"
      >
        <!-- 已添加的标点 -->
        <div 
          v-for="(marker, index) in (isEditMode ? currentMarkers : markers)" 
          :key="index"
          class="marker"
          :class="{
            'show-tooltip-bottom': shouldShowTooltipBottom(marker),
            'show-tooltip-right': shouldShowTooltipRight(marker),
            'draggable': isEditMode
          }"
          :style="{
            left: marker.x + '%',
            top: marker.y + '%'
          }"
          @mousedown.stop="handleMarkerMouseDown($event, marker, index)"
        >
          <el-popover
            placement="right"
            trigger="hover"
            popper-class="marker-popover"
            :disabled="isDraggingMarker && currentDraggingIndex === index"
          >
            <template #default>
              <div class="marker-tooltip-content">
                <span class="marker-title">{{ marker.title }}</span>
                <el-image 
                  v-if="marker.image" 
                  :src="marker.image" 
                  :alt="marker.title"
                  fit="contain"
                  :preview-src-list="[marker.image]"
                ></el-image>
                <div v-if="isEditMode" class="marker-actions">
                  <div class="action-button" @click="deleteMarker(index)">
                    <i class="el-icon-delete"></i>
                    <span>删除标点</span>
                  </div>
                </div>
              </div>
            </template>
            <template #reference>
              <div class="marker-point"></div>
            </template>
          </el-popover>
        </div>
      </div>

      <!-- 右键菜单 -->
      <div v-if="showContextMenu" 
        class="context-menu"
        :style="{
          position: 'fixed',
          left: contextMenuPosition.x + 'px',
          top: contextMenuPosition.y + 'px'
        }"
      >
        <el-menu>
          <el-menu-item @click="triggerBackgroundUpload">
            <i class="el-icon-folder-opened"></i>
            <span>本地选择</span>
          </el-menu-item>
          <el-menu-item @click="showBackgroundUrlInput">
            <i class="el-icon-link"></i>
            <span>输入URL</span>
          </el-menu-item>
        </el-menu>
      </div>

      <!-- 功能按钮组 -->
      <div class="floating-controls" :class="{ 'is-collapsed': isControlsCollapsed }">
        <div class="controls-header" @click.stop="toggleControls">
          <i class="el-icon-menu"></i>
        </div>
        <div class="controls-content" v-show="!isControlsCollapsed">
          <div class="button-group">
            <template v-if="!isEditMode">
              <el-button 
                @click.stop="startAddMarker" 
                type="primary"
                :class="{ 'is-active': isAddingMarker }"
                size="small"
                icon="el-icon-plus"
              >
                {{ addingButtonText }}
              </el-button>
              <el-button 
                @click.stop="startEditMode" 
                type="warning"
                size="small"
                icon="el-icon-edit"
              >
                编辑模式
              </el-button>
              <el-button 
                @click.stop="clearMarkers" 
                type="danger"
                size="small"
                icon="el-icon-delete"
              >
                清除所有
              </el-button>
            </template>
            <template v-else>
              <el-button @click.stop="saveChanges" type="success" size="small" icon="el-icon-check">
                保存
              </el-button>
              <el-button @click.stop="cancelChanges" type="danger" size="small" icon="el-icon-close">
                取消
              </el-button>
            </template>
          </div>
        </div>
      </div>

      <!-- 提示遮罩 -->
      <el-alert
        v-if="isAddingMarker"
        title="点击图片添加标点"
        type="info"
        :closable="false"
        class="marker-tip"
      ></el-alert>
      <el-alert
        v-if="isEditMode"
        title="编辑模式：拖动标点或右键更换背景"
        type="warning"
        :closable="false"
        class="marker-tip"
        :class="{ 'hidden': isTipHidden }"
      ></el-alert>

      <!-- 隐藏的文件上传输入框 -->
      <input 
        type="file" 
        ref="backgroundInput"
        accept="image/*"
        @change="handleBackgroundUpload"
        style="display: none;"
      >

      <!-- 缩放控制 -->
      <div class="zoom-controls">
        <div class="zoom-button" @click.stop="resetZoom">
          <i class="el-icon-refresh-right"></i>
          <span>{{ Math.round(scale * 100) }}%</span>
        </div>
      </div>
    </div>

    <!-- 标点输入弹窗 -->
    <el-dialog
      :visible.sync="showMarkerDialog"
      :title="isEditingMarker ? '编辑标点信息' : '添加标点信息'"
      width="30%"
      :close-on-click-modal="false"
      custom-class="marker-dialog"
    >
      <el-form :model="newMarker" label-width="80px">
        <el-form-item label="标点标识">
          <el-input v-model="newMarker.key" placeholder="请输入标点标识"></el-input>
        </el-form-item>
        <el-form-item label="标点标题">
          <el-input v-model="newMarker.title" placeholder="请输入标点标题"></el-input>
        </el-form-item>
        <el-form-item label="标点图片">
          <div class="image-upload">
            <el-upload
              class="upload-demo"
              action="#"
              :auto-upload="false"
              :show-file-list="false"
              :on-change="handleFileUpload"
            >
              <el-button size="small" type="primary">点击上传</el-button>
            </el-upload>
            <div class="divider">或</div>
            <el-input v-model="newMarker.imageUrl" placeholder="输入图片URL"></el-input>
          </div>
          <div v-if="newMarker.image" class="image-preview">
            <el-image 
              :src="newMarker.image" 
              fit="contain"
              :preview-src-list="[newMarker.image]"
            ></el-image>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelAddMarker">取 消</el-button>
          <el-button type="primary" @click="confirmAddMarker">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- URL输入弹窗 -->
    <el-dialog
      :visible.sync="showUrlDialog"
      title="输入背景图片URL"
      width="30%"
      :close-on-click-modal="false"
    >
      <el-input 
        v-model="backgroundUrl" 
        placeholder="请输入图片URL"
        @keyup.enter.native="confirmUrlInput"
      ></el-input>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelUrlInput">取 消</el-button>
          <el-button type="primary" @click="confirmUrlInput">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'ImageMarker',
  props: {
    // 容器宽度
    width: {
      type: String,
      default: '100%'
    },
    // 容器高度
    height: {
      type: String,
      default: '400px'
    },
    // 背景图片URL
    backgroundImage: {
      type: String,
      required: true
    },
    // 标记点数据
    value: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      isAddingMarker: false,
      isControlsCollapsed: true,
      markers: this.value,
      showMarkerDialog: false,
      newMarker: {
        x: 0,
        y: 0,
        key: '',
        title: '',
        image: '',
        imageUrl: ''
      },
      isEditMode: false,
      currentMarkers: [], // 用于编辑模式的临时数据
      originalMarkers: [], // 用于存储编辑前的数据
      currentBackgroundImage: this.backgroundImage,
      originalBackgroundImage: this.backgroundImage,
      showContextMenu: false,
      contextMenuPosition: { x: 0, y: 0 },
      scale: 1,
      minScale: 1,
      maxScale: 3,
      isDragging: false,
      dragStart: { x: 0, y: 0 },
      position: { x: 0, y: 0 },
      isDraggingMarker: false,
      markerDragStart: null,
      markerDragRAF: null,
      isEditingMarker: false,
      editingMarkerIndex: -1,
      dialogPosition: {
        '--dialog-height': 'auto'
      },
      markerMouseDownTime: 0,
      markerMouseDownPos: { x: 0, y: 0 },
      isTipHidden: false,
      moveRAF: null, // 添加requestAnimationFrame的引用
      showUrlDialog: false,
      backgroundUrl: '',
      dragRAF: null, // 添加 requestAnimationFrame 标识符
    }
  },
  computed: {
    addingButtonText() {
      if (!this.isAddingMarker) return '添加标点';
      return '请点击位置添加标点';
    },
    getCursor() {
      if (this.isAddingMarker) return 'crosshair';
      if (this.isDragging) return 'grabbing';
      if (this.isEditMode && event?.target?.closest('.marker')) return 'move';
      return this.scale > 1 ? 'grab' : 'default';
    }
  },
  watch: {
    value: {
      handler(newVal) {
        this.markers = newVal;
      },
      deep: true
    },
    markers: {
      handler(newVal) {
        this.$emit('input', newVal);
      },
      deep: true
    },
    'newMarker.imageUrl': {
      handler(newVal) {
        if (newVal) {
          this.newMarker.image = newVal;
        }
      }
    }
  },
  methods: {
    handleMarkerMouseDown(event, marker, index) {
      if (!this.isEditMode) return;
      
      // 记录点击时间和位置，用于区分点击和拖拽
      this.markerMouseDownTime = Date.now();
      this.markerMouseDownPos = {
        x: event.clientX,
        y: event.clientY
      };

      this.isDraggingMarker = true;
      this.currentDraggingIndex = index;
      
      const rect = this.$el.getBoundingClientRect();
      
      // 保存初始状态
      this.markerDragStart = {
        markerX: marker.x,
        markerY: marker.y,
        mouseX: event.clientX,
        mouseY: event.clientY,
        containerWidth: rect.width,
        containerHeight: rect.height
      };

      document.addEventListener('mousemove', this.handleGlobalMouseMove);
      document.addEventListener('mouseup', this.handleMarkerMouseUp);
    },

    handleGlobalMouseMove(event) {
      if (!this.isDraggingMarker) return;
      
      if (this.markerDragRAF) {
        cancelAnimationFrame(this.markerDragRAF);
      }
      
      this.markerDragRAF = requestAnimationFrame(() => {
        // 计算鼠标移动的距离（考虑缩放）
        const deltaX = (event.clientX - this.markerDragStart.mouseX) / this.scale;
        const deltaY = (event.clientY - this.markerDragStart.mouseY) / this.scale;
        
        // 计算新的标点位置（百分比）
        const newX = this.markerDragStart.markerX + (deltaX / this.markerDragStart.containerWidth) * 100;
        const newY = this.markerDragStart.markerY + (deltaY / this.markerDragStart.containerHeight) * 100;
        
        // 更新标点位置
        this.$set(this.currentMarkers, this.currentDraggingIndex, {
          ...this.currentMarkers[this.currentDraggingIndex],
          x: Math.max(0, Math.min(100, newX)),
          y: Math.max(0, Math.min(100, newY))
        });
      });
    },

    handleMarkerMouseUp(event) {
      // 判断是否为点击（时间间隔小于200ms且移动距离小于5px）
      const isClick = Date.now() - this.markerMouseDownTime < 200 && 
        Math.abs(event.clientX - this.markerMouseDownPos.x) < 5 &&
        Math.abs(event.clientY - this.markerMouseDownPos.y) < 5;

      if (isClick && this.isEditMode) {
        // 编辑当前标点
        const marker = this.currentMarkers[this.currentDraggingIndex];
        this.editMarker(marker, this.currentDraggingIndex);
      }

      this.isDraggingMarker = false;
      this.currentDraggingIndex = -1;
      
      if (this.markerDragRAF) {
        cancelAnimationFrame(this.markerDragRAF);
        this.markerDragRAF = null;
      }

      document.removeEventListener('mousemove', this.handleGlobalMouseMove);
      document.removeEventListener('mouseup', this.handleMarkerMouseUp);
    },

    editMarker(marker, index) {
      this.isEditingMarker = true;
      this.editingMarkerIndex = index;
      this.newMarker = {
        x: marker.x,
        y: marker.y,
        key: marker.key,
        title: marker.title,
        image: marker.image,
        imageUrl: ''
      };
      this.showMarkerDialog = true;
    },

    handleContainerClick(event) {
      if (!this.isAddingMarker || this.showMarkerDialog) return;
      
      if (event.target.closest('.marker-main')) {
        // 使用ref获取容器元素
        const container = this.$refs.container;
        if (!container) {
          console.error('Container element not found');
          return;
        }

        const rect = container.getBoundingClientRect();
        
        // 保持原有坐标计算逻辑
        const rawX = event.clientX - rect.left - this.position.x;
        const rawY = event.clientY - rect.top - this.position.y;
        
        const x = (rawX / (rect.width * this.scale)) * 100;
        const y = (rawY / (rect.height * this.scale)) * 100;

        this.newMarker.x = Math.max(0, Math.min(100, x));
        this.newMarker.y = Math.max(0, Math.min(100, y));
        
        this.showMarkerDialog = true;
        this.isAddingMarker = false;
        this.isTipHidden = true;
        
        // 在下一个事件循环中获取弹窗高度并更新位置  
        this.$nextTick(() => {
          const dialog = this.$el.querySelector('.marker-dialog');
          if (dialog) {
            const dialogHeight = dialog.offsetHeight;
            this.dialogPosition = {
              '--dialog-height': `${dialogHeight}px`
            };
          }
        });
      }
    },
    startAddMarker() {
      this.isAddingMarker = true;
      this.isControlsCollapsed = true;
      // 重置新标点数据
      this.newMarker = {
        x: 0,
        y: 0,
        key: '',
        title: '',
        image: '',
        imageUrl: ''
      };
    },
    confirmAddMarker() {
      if (!this.newMarker.key || !this.newMarker.title) {
        alert('请输入标点标识和标题');
        return;
      }
      
      if (this.isEditingMarker) {
        // 更新现有标点
        this.currentMarkers[this.editingMarkerIndex] = {
          x: this.newMarker.x,
          y: this.newMarker.y,
          key: this.newMarker.key,
          title: this.newMarker.title,
          image: this.newMarker.image
        };
        
        this.markers = JSON.parse(JSON.stringify(this.currentMarkers));
        this.$emit('marker-updated', {
          index: this.editingMarkerIndex,
          marker: this.currentMarkers[this.editingMarkerIndex]
        });
      } else {
        // 添加新标点
        this.markers.push({
          x: this.newMarker.x,
          y: this.newMarker.y,
          key: this.newMarker.key,
          title: this.newMarker.title,
          image: this.newMarker.image
        });
        
        this.$emit('marker-added', {
          x: this.newMarker.x,
          y: this.newMarker.y,
          key: this.newMarker.key,
          title: this.newMarker.title,
          image: this.newMarker.image
        });
      }
      
      this.resetAddMarker();
    },
    cancelAddMarker() {
      this.resetAddMarker();
    },
    resetAddMarker() {
      this.isAddingMarker = false;
      this.showMarkerDialog = false;
      this.isEditingMarker = false;
      this.editingMarkerIndex = -1;
      this.newMarker = {
        x: 0,
        y: 0,
        key: '',
        title: '',
        image: '',
        imageUrl: ''
      };
    },
    clearMarkers() {
      this.markers = [];
      this.$emit('markers-cleared');
    },
    toggleControls() {
      this.isControlsCollapsed = !this.isControlsCollapsed;
    },
    triggerFileInput() {
      this.$refs.fileInput.click();
    },
    handleFileUpload(file) {
      if (!file) return;
      
      const reader = new FileReader();
      reader.onload = (e) => {
        this.newMarker.image = e.target.result;
        this.newMarker.imageUrl = '';
      };
      reader.readAsDataURL(file.raw);
    },
    shouldShowTooltipBottom(marker) {
      // 当标点在上半部分时（y < 30%），提示框显示在下方
      return marker.y < 30;
    },
    shouldShowTooltipRight(marker) {
      // 当标点在左侧时（x < 20%），提示框显示在右侧
      return marker.x < 20;
    },
    startEditMode() {
      this.isEditMode = true;
      this.currentMarkers = JSON.parse(JSON.stringify(this.markers));
      this.originalMarkers = JSON.parse(JSON.stringify(this.markers));
      this.originalBackgroundImage = this.currentBackgroundImage;
      this.isControlsCollapsed = true;
      this.resetAddMarker(); // 确保关闭所有编辑状态
      this.isTipHidden = false; // 显示提示
    },
    saveChanges() {
      this.isEditMode = false;
      this.markers = JSON.parse(JSON.stringify(this.currentMarkers));
      this.isTipHidden = true; // 隐藏提示
      this.$emit('markers-updated', this.markers);
    },
    cancelChanges() {
      this.isEditMode = false;
      this.currentMarkers = JSON.parse(JSON.stringify(this.originalMarkers));
      this.isTipHidden = true; // 隐藏提示
      this.resetAddMarker(); // 确保关闭所有编辑状态
      
      // 恢复原始背景图片
      this.currentBackgroundImage = this.originalBackgroundImage;
    },
    handleRightClick(event) {
      if (!this.isEditMode) return;
      
      event.preventDefault();
      event.stopPropagation();
      
      // 计算菜单位置，确保在可视区域内
      const x = event.clientX;
      const y = event.clientY;
      
      this.contextMenuPosition = { x, y };
      this.showContextMenu = true;
      
      // 添加全局点击事件来关闭菜单
      const closeMenu = (e) => {
        // 如果点击的是菜单项，让菜单项的点击事件先执行
        if (!e.target.closest('.el-menu')) {
          this.showContextMenu = false;
          window.removeEventListener('click', closeMenu);
          window.removeEventListener('contextmenu', closeMenu);
        }
      };
      
      // 确保在下一个事件循环中添加事件监听
      setTimeout(() => {
        window.addEventListener('click', closeMenu);
        window.addEventListener('contextmenu', closeMenu);
      }, 0);
    },
    handleBackgroundUpload(event) {
      const file = event.target.files[0];
      if (!file) return;
      
      const reader = new FileReader();
      reader.onload = (e) => {
        this.currentBackgroundImage = e.target.result;
        // 清空 input 的值，确保可以重复选择同一个文件
        event.target.value = '';
      };
      reader.readAsDataURL(file);
    },
    triggerBackgroundUpload() {
      this.showContextMenu = false;
      // 确保在下一个事件循环中触发点击
      setTimeout(() => {
        this.$refs.backgroundInput.click();
      }, 0);
    },
    handleWheel(event) {
      // 只在添加标点时禁止缩放
      if (this.isAddingMarker) return;
      
      const delta = event.deltaY > 0 ? -0.1 : 0.1;
      const newScale = this.scale + delta;
      
      // 限制缩放范围在 100% - 300% 之间
      if (newScale >= this.minScale && newScale <= this.maxScale) {
        const oldScale = this.scale;
        this.scale = newScale;
        
        if (Math.abs(oldScale - delta) > 0.0001) {
          const rect = this.$el.getBoundingClientRect();
          const x = event.clientX - rect.left;
          const y = event.clientY - rect.top;
          
          const deltaX = x - (x * (this.scale / oldScale));
          const deltaY = y - (y * (this.scale / oldScale));
          
          this.position = {
            x: this.position.x + deltaX,
            y: this.position.y + deltaY
          };
        }
      }
    },
    resetZoom() {
      this.scale = 1;
      this.position = { x: 0, y: 0 };
    },
    handlePanStart(event) {
      // 只在缩放大于1时允许拖动，并且不在添加标点时
      if (this.scale <= 1 || this.isAddingMarker) return;
      
      // 如果是右键点击，不处理
      if (event.button === 2) return;
      
      // 如果点击的是标点，不处理拖动
      if (event.target.closest('.marker')) return;
      
      this.isDragging = true;
      this.dragStart = {
        x: event.clientX - this.position.x,
        y: event.clientY - this.position.y
      };
      
      // 添加移动事件监听
      document.addEventListener('mousemove', this.handlePanMove, { passive: true });
      document.addEventListener('mouseup', this.handlePanEnd, { once: true });
    },
    handlePanMove(event) {
      if (!this.isDragging) return;
      
      // 使用requestAnimationFrame优化性能
      if (this.moveRAF) {
        cancelAnimationFrame(this.moveRAF);
      }
      
      this.moveRAF = requestAnimationFrame(() => {
        // 计算新位置
        const newX = event.clientX - this.dragStart.x;
        const newY = event.clientY - this.dragStart.y;
        
        // 计算边界
        const maxX = (this.scale - 1) * this.$el.clientWidth;
        const maxY = (this.scale - 1) * this.$el.clientHeight;
        
        // 限制拖动范围
        this.position = {
          x: Math.max(-maxX, Math.min(0, newX)),
          y: Math.max(-maxY, Math.min(0, newY))
        };
      });
    },
    handlePanEnd() {
      this.isDragging = false;
      
      // 清除事件监听
      document.removeEventListener('mousemove', this.handlePanMove);
      
      if (this.moveRAF) {
        cancelAnimationFrame(this.moveRAF);
        this.moveRAF = null;
      }
    },
    contextMenuStyle() {
      return {
        left: `${this.contextMenuPosition.x}px`,
        top: `${this.contextMenuPosition.y}px`
      };
    },
    showBackgroundUrlInput() {
      this.showContextMenu = false;
      this.showUrlDialog = true;
      this.backgroundUrl = '';
    },
    confirmUrlInput() {
      if (!this.backgroundUrl) {
        alert('请输入图片URL');
        return;
      }
      
      // 创建Image对象验证URL是否有效
      const img = new Image();
      img.onload = () => {
        this.currentBackgroundImage = this.backgroundUrl;
        this.showUrlDialog = false;
      };
      img.onerror = () => {
        alert('图片URL无效，请检查后重试');
      };
      img.src = this.backgroundUrl;
    },
    cancelUrlInput() {
      this.showUrlDialog = false;
      this.backgroundUrl = '';
    },
    deleteMarker(index) {
      const deletedMarker = this.isEditMode ? this.currentMarkers[index] : this.markers[index];
      
      if (this.isEditMode) {
        this.currentMarkers.splice(index, 1);
      } else {
        this.markers.splice(index, 1);
      }
      
      // 发送删除事件
      this.$emit('marker-deleted', {
        index,
        marker: deletedMarker
      });
    },
  },
  mounted() {
    window.addEventListener('mouseup', this.handlePanEnd);
    window.addEventListener('mousemove', this.handlePanMove);
  },
  beforeDestroy() {
    // 确保清理所有事件监听和RAF
    if (this.moveRAF) {
      cancelAnimationFrame(this.moveRAF);
    }
    if (this.dragRAF) {
      cancelAnimationFrame(this.dragRAF);
    }
    if (this.markerDragRAF) {
      cancelAnimationFrame(this.markerDragRAF);
    }
    document.removeEventListener('mousemove', this.handlePanMove);
    document.removeEventListener('mouseup', this.handlePanEnd);
    document.removeEventListener('mousemove', this.handleGlobalMouseMove);
    document.removeEventListener('mouseup', this.handleMarkerMouseUp);
    window.removeEventListener('mouseup', this.handlePanEnd);
    window.removeEventListener('mousemove', this.handlePanMove);
  }
}
</script>

<style lang="scss" scoped>
.image-marker-container {
  position: relative;
  overflow: hidden;
  background: #f5f7fa;
  border-radius: 4px;
  
  .image-wrapper {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
  }

  .marker-main {
    user-select: none;
    transition: transform 0.1s ease;

    &.dragging {
      cursor: grabbing !important;
    }
  }

  .marker {
    position: absolute;
    transform: translate(-50%, -50%);
    cursor: pointer;
    z-index: 2;

    &.draggable {
      cursor: move;
    }

    .marker-point {
      width: 12px;
      height: 12px;
      background: #409EFF;
      border: 2px solid #fff;
      border-radius: 50%;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
      transition: all 0.3s ease;
      animation: pulse 2s infinite;

      &:hover {
        transform: scale(1.2);
        animation: none;
        background: #66b1ff;
      }
    }
  }
}

// 弹出框样式
.marker-popover {
  max-width: 300px;
  padding: 0;
  
  .marker-tooltip-content {
    padding: 12px;

    .marker-title {
      display: block;
      font-weight: bold;
      margin-bottom: 8px;
      color: #303133;
      font-size: 14px;
    }

    .marker-actions {
      display: flex;
      justify-content: flex-end;
      margin-top: 8px;
      padding-top: 8px;
      border-top: 1px solid #ebeef5;

      .action-button {
        padding: 4px 8px;
        font-size: 12px;
        color: #f56c6c;
        cursor: pointer;
        border-radius: 3px;
        transition: all 0.3s;
        display: flex;
        align-items: center;
        gap: 4px;

        &:hover {
          background: #fef0f0;
        }

        i {
          font-size: 14px;
        }
      }
    }

    .el-image {
      width: 100%;
      height: 160px;
      border-radius: 4px;
      display: block;
      
      ::v-deep {
        .el-image__inner {
          width: 100%;
          height: 100%;
          object-fit: contain;
          background: #f5f7fa;
        }
      }
    }
  }
}

// 控制面板
.floating-controls {
  position: absolute;
  right: 16px;
  top: 16px;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  z-index: 3;
  transition: all 0.3s ease;
  opacity: 0.4;

  &:hover {
    opacity: 1;
  }

  &.is-collapsed {
    .controls-content {
      width: 0;
      padding: 0;
      opacity: 0;
    }
  }

  .controls-header {
    padding: 8px;
    cursor: pointer;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 4px;
    transition: all 0.3s ease;

    i {
      font-size: 20px;
      color: #606266;
      transition: all 0.3s ease;
    }

    &:hover {
      background-color: #f5f7fa;
      i {
        color: #409EFF;
      }
    }
  }

  .controls-content {
    position: absolute;
    top: 0;
    right: 44px;
    background: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
    padding: 8px;
    transition: all 0.3s ease;
    opacity: 1;
    white-space: nowrap;
    transform: translateX(-12px);
    
    .button-group {
      display: flex;
      gap: 8px;

      .el-button {
        padding: 8px 12px;
        height: 32px;
        line-height: 1;
        
        &.is-active {
          background-color: #ecf5ff;
          border-color: #409EFF;
          color: #409EFF;
        }
      }
    }
  }
}

// 缩放控制
.zoom-controls {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 3;
  
  .zoom-button {
    display: flex;
    align-items: center;
    gap: 4px;
    background: #fff;
    border-radius: 4px;
    padding: 6px 12px;
    font-size: 13px;
    color: #606266;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
    cursor: pointer;
    transition: all 0.3s ease;
    opacity: 0.4;
    user-select: none;

    &:hover {
      opacity: 1;
      background: #f5f7fa;
      color: #409EFF;
    }

    i {
      font-size: 14px;
    }

    span {
      font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    }
  }
}

// 提示信息
.marker-tip {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  transition: all 0.3s ease;
  width: 20%;
  min-width: 150px;
  pointer-events: none;

  &.hidden {
    opacity: 0;
  }

  ::v-deep .el-alert {
    padding: 4px 12px;
    border-radius: 4px;
    background-color: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(4px);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
    
    .el-alert__content {
      padding: 0;
    }
    
    .el-alert__title {
      font-size: 13px;
      line-height: 1.4;
      white-space: nowrap;
    }
  }
}

// 对话框自定义样式
.marker-dialog {
  .image-upload {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;

    .divider {
      color: #909399;
    }

    .el-input {
      flex: 1;
    }
  }

  .image-preview {
    margin-top: 12px;
    text-align: center;

    .el-image {
      max-width: 100%;
      max-height: 200px;
      border-radius: 4px;
    }
  }
}

// 右键菜单样式
.context-menu {
  z-index: 2000;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  
  ::v-deep .el-menu {
    border: none;
    padding: 4px 0;
    
    .el-menu-item {
      height: 36px;
      line-height: 36px;
      padding: 0 16px;
      font-size: 14px;
      color: #606266;
      
      i {
        margin-right: 8px;
        font-size: 16px;
      }
      
      &:hover {
        background-color: #ecf5ff;
        color: #409EFF;
      }
      
      &:active {
        background-color: #e6f2ff;
      }
    }
  }
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(64, 158, 255, 0.4);
  }
  70% {
    box-shadow: 0 0 0 6px rgba(64, 158, 255, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(64, 158, 255, 0);
  }
}
</style> 